﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using Autofac;
using ZilLion.Service.Core.ConfigManager.Manager;
using ZilLion.Service.Core.Infrastructure;
using ZilLion.Service.Core.Log;

namespace ZilLion.Service.Core.Ioc
{
    /// <summary>
    ///     Autofac配置
    /// </summary>
    public static class IocConfig
    {
        /// <summary>
        ///     注册Api组件
        /// </summary>
        public static Dictionary<string, IComponentLoader> ComponentLoaderCache { get; set; } =
            new Dictionary<string, IComponentLoader>();

        private static IComponentLoader GetComponentLoader(Assembly assembly)
        {
            var controllerRegisterType =
                assembly.GetTypes()
                    .FirstOrDefault(x => x.GetInterfaces().Any(y => y.FullName == typeof(IComponentLoader).FullName));
            if (controllerRegisterType == null) return null;
            var loader = (IComponentLoader) Activator.CreateInstance(controllerRegisterType);
            loader.SetComponentAssembly(assembly);
            return loader;
        }

        /// <summary>
        ///     Initializes and configures instance of <see cref="IContainer" />.
        /// </summary>
        /// <param name="builder"></param>
        /// <param name="rootAssembly"></param>
        public static void Configure(ContainerBuilder builder, Assembly rootAssembly)
        {
            #region 注册各模块组件

            //入口组件注册
            var rootComponentLoader = GetComponentLoader(rootAssembly);
            if (rootComponentLoader != null)
                if (!ComponentLoaderCache.ContainsKey("root"))
                    ComponentLoaderCache.Add("root", rootComponentLoader);


            foreach (var module in ZilLionConfigurationManager.GetConfigInstance<WebApiAppConfig>().WebModules)
                try
                {
                    var componentLoader = GetComponentLoader(Assembly.Load($"ZilLion.Service.{module}.Controllers"));

                    if (componentLoader == null) continue;
                    if (!ComponentLoaderCache.ContainsKey(module.ToLower()))
                        ComponentLoaderCache.Add(module.ToLower(), componentLoader);
                }
                catch (FileNotFoundException ex)
                {
                    ZilLionLogManager.Instance().Error(ex);
                }
            foreach (var register in ComponentLoaderCache.Values)
                builder.RegisterModule(register);
            builder.RegisterBuildCallback(IocContainer.InitContainer);
            #endregion
        }
    }
}